package com.zzb.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * 日期工具类 zb.zhang 2013-7-23
 */
public class DateUtil {
	// ~ Static fields/initializers
	// =============================================

	private static String defaultDatePattern = null;
	public static final String HHMM = "HH:mm";
	public static final String YYYYMM = "yyyy-MM";
	public static final String YYYYMMDD = "yyyy-MM-dd";
	public static final String YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";
	public static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";
	public static final String HHMMSS = "HH:mm:ss";

	// ~ Methods
	// ================================================================

	/**
	 * 获取默认日期格式
	 * 
	 * @return 默认的时间格式，未配置返回 (yyyy-MM-dd)
	 */
	public static synchronized String getDegaultDatePattern() {
		try {
			defaultDatePattern = ResourceBundle.getBundle(
					"ApplicationResources", Locale.getDefault()).getString(
					"date.format");
		} catch (MissingResourceException mse) {
			defaultDatePattern = "yyyy-MM-dd";
		}
		return defaultDatePattern;
	}

	/**
	 * 获取默认日期时间格式
	 * 
	 * @return 默认日期时间格式，未配置日期返回 (yyyy-MM-dd HH:mm:ss)
	 */
	public static String getDefaultDateTimePattern() {
		return DateUtil.getDegaultDatePattern() + " HH:mm:ss";
	}

	/**
	 * 获取基于默认日期格式的时间格式化字符串
	 * 
	 * @param date
	 *            要格式化的时间
	 * @return 根据默认格式转换的时间，传入为空则返回当前时间
	 */
	public static String getStringOfDate(Date date) {
		SimpleDateFormat df = new SimpleDateFormat(getDegaultDatePattern());
		if (date == null) {
			date = new Date();
		}
		return df.format(date);
	}

	/**
	 * 获取基于默认日期时间格式的时间格式化字符串
	 * 
	 * @param date
	 *            要格式化的时间
	 * @return 根据默认格式转换的时间，传入为空则返回当前时间
	 */
	public static String getStringOfDateTime(Date date) {
		SimpleDateFormat df = new SimpleDateFormat(getDefaultDateTimePattern());
		if (date == null) {
			date = new Date();
		}
		return df.format(date);
	}
	public static String getStringOfDateTime() {
		return getStringOfDateTime(new Date());
	}

	/**
	 * 根据传入格式字符串和时间字符串转换为对应的Date对象
	 * 
	 * @param mask
	 *            时间格式字符串
	 * @param dateStr
	 *            时间字符串
	 * @return 转换后的Date实例
	 * @see java.text.SimpleDateFormat
	 * @throws ParseException
	 */
	public static Date getDateFromStringAsMask(String mask, String dateStr)
			throws ParseException {
		SimpleDateFormat df = null;
		Date date = null;
		df = new SimpleDateFormat(mask);
		try {
			date = df.parse(dateStr);
		} catch (ParseException pe) {
			throw new ParseException(pe.getMessage(), pe.getErrorOffset());
		}
		return date;
	}

	/**
	 * 根据传入格式字符串和时间字符串转换为对应的Calaendar对象
	 * 
	 * @param mask
	 *            时间格式字符串
	 * @param date
	 *            时间字符串
	 * @return Calaendar的对应实例
	 * @throws ParseException
	 */
	public static Calendar getCalendarFromStringAsMask(String mask, String date)
			throws ParseException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getDateFromStringAsMask(mask, date));
		return calendar;
	}

	/**
	 * 根据传入的格式字符串和Date实例转换为对应的时间字符串
	 * 
	 * @param mask
	 *            时间格式字符串
	 * @param date
	 *            Date实例
	 * @return date用传入的时间格式字符串格式化后的字符串，null返回当前时间
	 * @see java.text.SimpleDateFormat
	 */
	public static final String getStringFromDateAsMask(String mask, Date date) {
		SimpleDateFormat df = new SimpleDateFormat(mask);
		if (date == null) {
			date = new Date();
		}
		return df.format(date);
	}

	/**
	 * 将日期+时间，构造一个日期（包含时间）
	 * 
	 * @param date
	 * @param time
	 * @return
	 */
	public static Date getDateByDateAndTime(Date date, String time) {
		if (date == null)
			return null;
		Calendar c = Calendar.getInstance();
		c.clear();
		c.setTime(date);
		if (time != null && time.trim().length() > 0) {
			String[] sa = time.trim().split("[:.]");
			if (sa != null && sa.length >= 2) {
				c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(sa[0]));
				c.set(Calendar.MINUTE, Integer.valueOf(sa[1]));
				if (sa.length >= 3)
					c.set(Calendar.SECOND, Integer.valueOf(sa[2]));
				if (sa.length == 4)
					c.set(Calendar.MILLISECOND, Integer.valueOf(sa[3]));
			}
		}
		return c.getTime();
	}

	/**
	 * 获取列表中最早的日期
	 * 
	 * @param dates
	 *            时间的列表
	 * @return 列表中最早的时间
	 */
	public static Date getMinDate(List<Date> dates) {
		if (dates == null || dates.size() == 0)
			return null;
		Date minDate = dates.get(0);
		for (Date dtemp : dates) {
			if (minDate.getTime() > dtemp.getTime()) {
				minDate = dtemp;
			}
		}
		return minDate;
	}

	/**
	 * 获取列表中最晚的日期
	 * 
	 * @param dates
	 *            时间的列表
	 * @return 列表中最晚的时间
	 */
	public static Date getMaxDate(List<Date> dates) {
		if (dates == null || dates.size() == 0)
			return null;
		Date maxDate = dates.get(0);
		for (Date dtemp : dates) {
			if (maxDate.getTime() < dtemp.getTime()) {
				maxDate = dtemp;
			}
		}
		return maxDate;
	}

	/**
	 * 将日期字符串转换为Calendar类型，间隔符合支持:/-. sDate:日期字符串
	 * 
	 * @param date
	 *            年月日字符串
	 * @param time
	 *            时间字符串
	 * @return
	 */
	public static Calendar getCalendarByDateAndTime(String date, String time) {
		if (date == null || date.trim().length() == 0) {
			return null;
		}
		Calendar c = Calendar.getInstance();
		c.clear();
		String[] sa = date.split("[-/.]");
		c.set(Integer.valueOf(sa[0]), Integer.valueOf(sa[1]) - 1,
				Integer.valueOf(sa[2]));
		// 处理有时间的情况
		if (time != null && time.trim().length() > 0) {
			String[] sa2 = time.split("[:.]");
			if (sa2.length >= 2) { // 10:00
				c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(sa2[0]));
				c.set(Calendar.MINUTE, Integer.valueOf(sa2[1]));
			}
			if (sa2.length >= 3) { // 10:22:59
				c.set(Calendar.SECOND, Integer.valueOf(sa2[2]));
			}
			if (sa2.length >= 4) {
				c.set(Calendar.MILLISECOND, Integer.valueOf(sa[3]));
			}
		}
		return c;
	}

	/**
	 * 根据两个日期，获取这两个日期中间所有的日期列表
	 * 
	 * @param sDate
	 * @param eDate
	 * @return
	 */
	public static List<Date> getDatesBetweenDays(String sDate, String eDate) {
		List<Date> ls = new ArrayList<Date>();
		Calendar sC = getCalendarByDateAndTime(sDate, null);
		Calendar eC = getCalendarByDateAndTime(eDate, null);
		do {
			ls.add(sC.getTime());
			sC.add(Calendar.DAY_OF_MONTH, 1);
		} while (sC.before(eC));

		if (sC.getTimeInMillis() == eC.getTimeInMillis()) {
			ls.add(eC.getTime());
		}
		return ls;
	}

	/**
	 * @Title: isWeekend
	 * @Description: 判断日期是否为周末
	 * @param date
	 *            日期参数
	 * @param pattern
	 *            格式类型
	 * @return boolean
	 * @throws ParseException
	 */
	public static boolean isWeekend(String date, String pattern)
			throws ParseException {
		Calendar cal = getCalendarFromStringAsMask(pattern, date);
		int day = cal.get(Calendar.DAY_OF_WEEK);
		return (day == Calendar.SATURDAY || day == Calendar.SUNDAY);
	}

	/**
	 * 取某月中有多少天
	 * 
	 * @param month
	 *            (yyyy-MM)
	 * @return
	 * @throws ParseException
	 */
	public static int getdays(String yyyyMM) throws ParseException {
		Calendar calendar = getCalendarFromStringAsMask(YYYYMM, yyyyMM);
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * @param DATE1
	 * @param DATE2
	 * @param format格式自定义
	 *            （yyyy-MM,yyyy-MM-dd）
	 * @return 比较两个日期的大小
	 *         (返回0：则相等如：（2012-12，2012-12）1：则第一个日期在第二个日期后如：（2012-12，2012
	 *         -11）-1：则第一个日期在每个日期前（2012-11，2012-12）) author:czl
	 */
	public static int compare_date(String DATE1, String DATE2, String format) {
		DateFormat df = new SimpleDateFormat(format);
		try {
			Date dt1 = df.parse(DATE1);
			Date dt2 = df.parse(DATE2);
			if (dt1.after(dt2)) {
				return 1;
			} else if (dt1.before(dt2)) {
				return -1;
			} else {
				return 0;
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return 0;
	}

	/**
	 * @param nowDate
	 *            2012-11
	 * @return 2012-11-01 获取条件月的第一天
	 * @throws ParseException
	 */
	public static Date getMonthFirstDate(String nowDate) throws ParseException {
		return getDateFromStringAsMask(YYYYMM, nowDate);
	}

	/**
	 * @param nowDate
	 *            如：2012-11
	 * @return 2012-11-30 获取条件月的最后一天
	 * @throws ParseException
	 */
	public static Date getMonthLastDate(String nowDate) throws ParseException {
		int days = getdays(nowDate);
		Calendar calendar = getCalendarFromStringAsMask(YYYYMM, nowDate);
		calendar.set(Calendar.DAY_OF_MONTH, days);
		return calendar.getTime();
	}

	/**
	 * @param nowDate
	 *            如：（2012-09）
	 * @return 2012-08 获取当前年月的前一月
	 * @throws ParseException
	 */
	public static String getDateBeforeMonth(String nowDate)
			throws ParseException {
		Calendar calendar = getCalendarFromStringAsMask(YYYYMM, nowDate);
		calendar.add(Calendar.MONTH, -1);
		return getStringFromDateAsMask(YYYYMM, calendar.getTime());
	}
}
